package TCPDemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Tcp版本的 "服务器"
 *
 * ServerSocket: 给 "服务器" 用的,用来监听端口
 * Socket: 给 "服务器" && "客户端" 用的, 用来接收数据
 */
public class TcpEchoServer {
        private ServerSocket serverSocket = null;

        public TcpEchoServer(int port) throws IOException {
            serverSocket = new ServerSocket(port);
        }

        public void start() throws IOException {
            System.out.println("服务器启动!");
            while(true){
                // 1.调用 accept() 接收客户端连接
                // 如果没有客户端建立连接 会阻塞
                Socket clientSocket = serverSocket.accept();
                //2.处理这个连接
                processConnection(clientSocket);
            }
        }
        // 使用方法处理连接
        public void processConnection(Socket clientSocket) throws IOException {
            System.out.printf("[%s:%d] 客户端启动!",clientSocket.getInetAddress().toString(),clientSocket.getPort());
            //处理请求
            try(InputStream inputStream = clientSocket.getInputStream();
                OutputStream outputStream = clientSocket.getOutputStream()){
                while(true){
                    //1.读取命令并解析
                    Scanner scanner = new Scanner(inputStream);
                    if(!scanner.hasNext()){
                        //读完了 断开连接
                        System.out.printf("[%s:%d] 客户端下线!",clientSocket.getInetAddress().toString(),
                                clientSocket.getPort());
                        break;
                    }
                    String request = scanner.next();
                    //2.根据请求计算响应
                    String response = process(request);

                    //3.把响应写回客户端
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    printWriter.println(response);//注意 这里使用的是println 带有'\n'
                    //4.刷新缓冲区
                    printWriter.flush();

                    // 打印结果
                    System.out.printf("[%s:%d] req: %s; resp: %s\n",clientSocket.getInetAddress().toString(),
                            clientSocket.getPort(),request,response);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }finally {
                //为什么要进行 close()?
                // Socket本质上是一个 "文件" 一个进程打开的文件是有限的 -> 文件描述符表
                clientSocket.close();
            }
        }

        public String process(String request){
            return request;
        }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(6666);
        server.start();
    }
}
